﻿using System;
using System.Reflection;

namespace LayeredArchitectureSample.Services
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly domainAssembly =
                Assembly.LoadFrom(@"D:\projects\VS2010.Current\LineOfBusinessApplication\DomainModel\bin\Debug\DomainModel.dll");

            foreach (Type type in domainAssembly.GetTypes())
            {
                if (type.BaseType != null && type.BaseType.Name.Equals("DomainObject"))
                {
                    ConstructorInfo[] ctors = type.GetConstructors();

                    if (ctors.Length > 1)
                    {
                        throw new NotSupportedException(/*TODO*/);
                    }

                    foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        string newPropertyType = propertyInfo.PropertyType.FullName;

                        if (propertyInfo.PropertyType.IsGenericType)
                        {
                            Type[] genericArguments = propertyInfo.PropertyType.GetGenericArguments();

                            if (genericArguments.Length > 1)
                            {
                                throw new NotSupportedException(/*TODO*/);
                            }

                            string genericArgumentName = genericArguments[0].FullName;

                            if (genericArguments[0].Assembly.FullName.Equals(domainAssembly.FullName))
                            {
                                genericArgumentName = genericArguments[0].FullName + "Dto";
                            }

                            string baseName =
                                propertyInfo.PropertyType.FullName.Remove(propertyInfo.PropertyType.FullName.IndexOf('`'));

                            newPropertyType = baseName + String.Format("<{0}>", genericArgumentName);
                        }
                        else if (propertyInfo.PropertyType.Assembly.FullName.Equals(domainAssembly.FullName))
                        {
                            newPropertyType = propertyInfo.PropertyType.FullName + "Dto";
                        }

                        string propertyDefinition =
                            String.Format("public {0} {1} {{ get; {2}set;}}",
                            newPropertyType,
                            propertyInfo.Name,
                            propertyInfo.CanWrite ? "" : "private ");

                        Console.WriteLine(propertyDefinition);
                    }

//                    foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
//                    {
//                        Console.WriteLine(fieldInfo.Name);
//                    }

                    Console.WriteLine(type.FullName);
                }
            }

            Console.ReadLine();

//            var businessService;
//
//            var trips = businessService.GetAllTrips();
//
//            businessService.AddRoute(route);
//
//            try
//            {
//                trips[0].Ship(route, wares);
//
//                trips[0].MarkAsArrivedToFinalDestination();
//            }
//            catch (InvalidOperationException)
//            {
//                throw;
//            }

//            EntityConnectionStringBuilder entityConnectionStringBuilder = new EntityConnectionStringBuilder();
//
//            entityConnectionStringBuilder.Provider = "System.Data.SqlClient";
//
            // search all loaded assemblies for the metadata info
//            entityConnectionStringBuilder.Metadata = "res://*";
//
//            entityConnectionStringBuilder.ProviderConnectionString =
//                @"Data Source=.\SQLEXPRESS;Initial Catalog=LobDemo;Integrated Security=True";
//
//            using (var context = new LogisticSampleStupid(entityConnectionStringBuilder.ConnectionString))
//            {
//                var allTrips =
//                    (from Trip trip in context.Trips
//                     select trip).ToList();
//
//                foreach (Trip trip in allTrips)
//                {
//                    Console.WriteLine(trip.Id);
//                }
//            }
        }
    }
}